package com.chuhe.starry.dao;

import cn.hutool.crypto.digest.DigestUtil;
import com.chuhe.common.constans.MyConstants;
import com.chuhe.common.domain.dto.TokenUserInfoDto;
import com.chuhe.common.domain.entity.UserContact;
import com.chuhe.common.domain.entity.UserInfo;
import com.chuhe.common.domain.vo.req.AdminLoadUserReq;
import com.chuhe.common.utils.AppConfig;
import com.chuhe.common.utils.RedisComponet;
import com.chuhe.starry.mapper.UserInfoMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuhe.starry.service.ChatSessionUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Date;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author <a href="张楚河">chuhe_z</a>
 * @since 2025-05-08
 */
@Service
public class UserInfoDao extends ServiceImpl<UserInfoMapper, UserInfo> {
    @Autowired
    private AppConfig appConfig;
    @Autowired
    private RedisComponet redisComponet;
    @Autowired
    private ChatSessionUserService chatSessionUserService;

    /**
     * 查询邮箱
     * @Author: 楚河
     * @Date: 2025-05-11 11:48
     */
    public UserInfo selectEmail(String email) {
        return lambdaQuery()
                .eq(UserInfo::getEmail, email)
                .one();
    }
    /**
     * 根据id查询用户
     * @Author: 楚河
     * @Date: 2025-05-15 22:53
     */
    public UserInfo selectByUserId(String contactId) {
        return lambdaQuery()
                .eq(UserInfo::getUserId, contactId)
                .one();
    }
    /**
     * 保存用户信息
     * @Author: 楚河
     * @Date: 2025-05-17 22:34
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfo(UserInfo userInfo, MultipartFile avatarFile, MultipartFile avatarCover) throws IOException {
        //头像处理
        if(avatarFile != null){
            String baseFolder = appConfig.getProjectFolder() + MyConstants.FILE_FOLDER_FILE;
            File targerFileFolder = new File(baseFolder + MyConstants.FILE_FOLDER_AVATAR_NAME);
            if(!targerFileFolder.exists()){
                targerFileFolder.mkdirs();
            }
            String filePath = targerFileFolder.getPath() + File.separator + userInfo.getUserId() + MyConstants.IMAGE_SUFFIX;
            avatarFile.transferTo(new File(filePath));
            avatarCover.transferTo(new File(filePath + MyConstants.COVER_IMAGE_SUFFIX));
        }
        UserInfo info = selectByUserId(userInfo.getUserId());
        updateByUserId(userInfo,userInfo.getUserId());
        //更新相关冗余表字段
        String contactNameUpdate = null;
        if(!info.getNickName().equals(userInfo.getNickName())){
            contactNameUpdate = userInfo.getNickName();
        }
        if(Objects.isNull(contactNameUpdate)){
            return;
        }
        //更细token中的昵称
        TokenUserInfoDto tokenUserInfoDto = redisComponet.getTokenuserInfoDtoByUserId(userInfo.getUserId());
        tokenUserInfoDto.setNickName(contactNameUpdate);
        redisComponet.saveTokenUserInfoDto(tokenUserInfoDto);
        //发送消息
        chatSessionUserService.updateRedundanceInfo(contactNameUpdate, userInfo.getUserId());
    }

    /**
     * 更新信息
     * @Author: 楚河
     * @Date: 2025-05-17 23:02
     */
    private void updateByUserId(UserInfo userInfo, String userId) {
        lambdaUpdate()
                .eq(UserInfo::getUserId, userId)
                .set(UserInfo::getNickName,userInfo.getNickName())
                .set(UserInfo::getSex,userInfo.getSex())
                .set(UserInfo::getJoinType,userInfo.getJoinType())
                .set(UserInfo::getAreaName,userInfo.getAreaName())
                .set(UserInfo::getPersonalSignature,userInfo.getPersonalSignature())
                .update();
    }

    /**
     * 修改密码
     * @Author: 楚河
     * @Date: 2025-05-17 22:44
     */
    public void updatePassword(String userId, String password) {
        lambdaUpdate()
                .eq(UserInfo::getUserId, userId)
                .set(UserInfo::getPassword, DigestUtil.md5Hex(password))
                .update();
    }
    /**
     * 查询用户数量
     * @Author: 楚河
     * @Date: 2025-05-18 10:38
     */
    public int selectUserCount() {
        return lambdaQuery()
                .count();
    }

    /**
     * 查询所有用户
     * @Author: 楚河
     * @Date: 2025-05-18 10:43
     */
    public List<UserInfo> selectAllUser(AdminLoadUserReq req) {
        return lambdaQuery()
                .eq(StringUtils.isNotBlank(req.getUserId()),UserInfo::getUserId, req.getUserId())
                .like(StringUtils.isNotBlank(req.getNickNameFuzzy()),UserInfo::getNickName,req.getNickNameFuzzy())
                .orderByDesc(UserInfo::getLastLoginTime)
                .list();
    }
    /**
     * 根据id修改用户状态
     * @Author: 楚河
     * @Date: 2025-05-18 11:02
     */
    public void updateUserStatusByUserId(Integer status, String userId) {
        lambdaUpdate()
                .eq(UserInfo::getUserId,userId)
                .set(UserInfo::getStatus,status)
                .update();
    }
    /**
     * 根据邮箱查询
     * @Author: 楚河
     * @Date: 2025-05-18 11:27
     */
    public UserInfo selectByEmail(String email) {
        return lambdaQuery()
                .eq(UserInfo::getEmail, email)
                .one();
    }
    /**
     * 更新用户最新离线时间
     * @Author: 楚河
     * @Date: 2025-05-21 17:02
     */
    public void updateLastOffTimeByUserId(String userId) {
        lambdaUpdate()
                .eq(UserInfo::getUserId,userId)
                .set(UserInfo::getLastOffTime,System.currentTimeMillis())
                .update();
    }
    /**
     * 更新用户最后连接时间
     * @Author: 楚河
     * @Date: 2025-05-21 17:06
     */
    public void updateLastLoginTimeByUserId(String userId) {
        lambdaUpdate()
                .eq(UserInfo::getUserId,userId)
                .set(UserInfo::getLastLoginTime,new Date())
                .update();
    }
}
